using System.Security.Cryptography;
using System.Text;

namespace Vin.Tool.Core.EncryptCategory;

public class RsaEncryptTool
{
    #region 导出/转换秘钥

    public static (string, string) GenerateSecretKeyPem(int length = 2048)
    {
        var (publicKey, privateKey) = GenerateSecretKey(length);
        return SecretKeyToPem(publicKey, privateKey);
    }

    public static (string, string) GenerateSecretKey(int length = 2048)
    {
        using var rsa = RSA.Create(length);
        return (Convert.ToBase64String(rsa.ExportRSAPublicKey()), Convert.ToBase64String(rsa.ExportRSAPrivateKey()));
    }

    public static (string, string) SecretKeyToPem(string publicKey, string privateKey)
    {
        using var rsa = RSA.Create();
        rsa.ImportRSAPublicKey(Convert.FromBase64String(publicKey), out _);
        rsa.ImportRSAPrivateKey(Convert.FromBase64String(privateKey), out _);
        return (rsa.ExportRSAPublicKeyPem(), rsa.ExportRSAPrivateKeyPem());
    }

    #endregion

    #region 加密

    #region PEM

    public static string EncryptPem(string content, string publicKey, RSAEncryptionPadding padding, int length = 2048)
    {
        using var rsa = RSA.Create(length);
        rsa.ImportFromPem(publicKey);
        return Convert.ToBase64String(rsa.Encrypt(Encoding.UTF8.GetBytes(content), padding));
    }

    public static string EncryptPem(string content, string publicKey, int length = 2048)
    {
        return EncryptPem(content, publicKey, RSAEncryptionPadding.Pkcs1, length);
    }

    #endregion

    #region 秘钥

    public static string Encrypt(string content, string publicKey, RSAEncryptionPadding padding, int length = 2048)
    {
        using var rsa = RSA.Create(length);
        rsa.ImportRSAPublicKey(Convert.FromBase64String(publicKey), out _);
        return Convert.ToBase64String(rsa.Encrypt(Encoding.UTF8.GetBytes(content), padding));
    }

    public static string Encrypt(string content, string publicKey, int length = 2048)
    {
        return Encrypt(content, publicKey, RSAEncryptionPadding.Pkcs1, length);
    }

    #endregion

    #region SubjectInfo

    public static string EncryptSubjectInfo(string content, string publicKey, RSAEncryptionPadding padding,
        int length = 2048)
    {
        using var rsa = RSA.Create(length);
        rsa.ImportSubjectPublicKeyInfo(Convert.FromBase64String(publicKey), out _);
        return Convert.ToBase64String(rsa.Encrypt(Encoding.UTF8.GetBytes(content), padding));
    }

    public static string EncryptSubjectInfo(string content, string publicKey, int length = 2048)
    {
        return EncryptSubjectInfo(content, publicKey, RSAEncryptionPadding.Pkcs1, length);
    }

    #endregion

    #endregion

    #region 解密

    #region PEM

    public static string DecryptPem(string content, string privateKey, RSAEncryptionPadding padding, int length = 2048)
    {
        using var rsa = RSA.Create(length);
        rsa.ImportFromPem(privateKey);
        return Encoding.UTF8.GetString(rsa.Decrypt(Convert.FromBase64String(content), padding));
    }

    public static string DecryptPem(string content, string privateKey, int length = 2048)
    {
        return DecryptPem(content, privateKey, RSAEncryptionPadding.Pkcs1, length);
    }

    #endregion

    #region 秘钥

    public static string Decrypt(string content, string privateKey, RSAEncryptionPadding padding, int length = 2048)
    {
        using var rsa = RSA.Create(length);
        rsa.ImportRSAPrivateKey(Convert.FromBase64String(privateKey), out _);
        return Encoding.UTF8.GetString(rsa.Decrypt(Convert.FromBase64String(content), padding));
    }

    public static string Decrypt(string content, string privateKey, int length = 2048)
    {
        return Decrypt(content, privateKey, RSAEncryptionPadding.Pkcs1, length);
    }

    #endregion

    #endregion
}